package quoridor;

import java.util.NoSuchElementException;

public class QuoridorGame extends AbstractGame {
	Player playerBlack;
	Player playerWhite;
	
	public QuoridorGame(DecisionMakerType playerWhiteBrain,
			DecisionMakerType playerBlackBrain, String gameString) {
		super(playerWhiteBrain, playerBlackBrain, gameString);
		playerWhite = new QuoridorPlayer (playerWhiteBrain, PlayerColour.WHITE, gameBoard);
		playerBlack = new QuoridorPlayer (playerBlackBrain, PlayerColour.BLACK, gameBoard);
	}

	public QuoridorGame(DecisionMakerType playerWhiteBrain,
			DecisionMakerType playerBlackBrain) {
		super(playerWhiteBrain, playerBlackBrain);
		playerWhite = new QuoridorPlayer (playerWhiteBrain, PlayerColour.WHITE, gameBoard);
		playerBlack = new QuoridorPlayer (playerBlackBrain, PlayerColour.BLACK, gameBoard);
	}

	@Override
	public boolean playGame() {
		boolean gameExited = false;
		Player currentPlayer;
		
		//set initial player
		switch (gameBoard.currentPlayer()) {
			case BLACK:
				currentPlayer = playerBlack;
				break;
			case WHITE:
				currentPlayer = playerWhite;
				break;
			default:
				throw new IllegalStateException();
		}
		

		//display the initial board
		while (gameBoard.isOver() == false && gameExited == false) {
			gameExited = playerTurn(currentPlayer);
			
			//prepare next player;
			switch (currentPlayer.getPlayerColour()) {
				case BLACK: 
					currentPlayer = playerWhite;
					assert(currentPlayer.equals(gameBoard.currentPlayer()) || gameExited);
					break;
				case WHITE: 
					currentPlayer = playerBlack;
					assert(currentPlayer.equals(gameBoard.currentPlayer()) || gameExited);
					break;
				case INVALID:
					throw new NoSuchElementException();
			}
		}
		
		if (gameBoard.isOver())	{
		   switch (currentPlayer.getPlayerColour()) {
         case BLACK: 
            currentPlayer = playerWhite;
            assert(currentPlayer.equals(gameBoard.currentPlayer()) || gameExited);
            break;
         case WHITE: 
            currentPlayer = playerBlack;
            assert(currentPlayer.equals(gameBoard.currentPlayer()) || gameExited);
            break;
      }
			QuoridorDisplay.instance().printVictory(gameBoard, currentPlayer.getPlayerColour());
		}
		
		return gameBoard.isOver() || gameExited;
	}
	
	private boolean playerTurn(Player player) {
		Action playerAction;
		boolean gameExited = false;

		try {
			playerAction = player.takeTurn();
			while (playerAction.getType() != ActionType.MOVE && gameExited == false) {
				if (playerAction.getType() == ActionType.SAVE) {
					saveGame();
				} else if (playerAction.getType() == ActionType.EXIT) {
					exitGame();
					gameExited = true;
					continue;
				} else if (playerAction.getType() == ActionType.UNDO) {
					gameBoard.undoMove();
				} else if (playerAction.getType() == ActionType.REDO) {
					gameBoard.redoMove();
				}
				
				playerAction = player.takeTurn();
			}
		} catch (Exception e) {
			return true;
		}
		
		return gameExited;
	}

}
